﻿/// <reference path="../../Core.ts" />

module Supernova {

    export class GameUI implements UI.ISwitchableUI {

        // Set up the left panel

        public newFacilityButton = new UI.Button({ top: 0, height: 30, enabled: false, text: '🏠 Facilities', onClick: this.handleNewFacilityButtonClicked });
        public newScienceButton = new UI.Button({ top: 40, height: 30, enabled: false, text: 'ⓢ Research', onClick: this.handleNewScienceButtonClicked });
        public newShipButton = new UI.Button({ top: 80, height: 30, text: '△ Shipyard', onClick: this.handleNewShipButtonClicked });
        public pauseButton = new UI.Button({ bottom: 0, height: 30, text: 'Pause', onClick: this.handlePauseButtonClicked });
        public optionsButton = new UI.Button({ bottom: 40, height: 30, text: 'Options', onClick: this.handleOptionsButtonClicked });
        public leftPanel = new UI.Panel({ left: 10, top: 10, width: 120, bottom: 10 });

        // Set up the new facility panel
        public buildCommsButton = new UI.Button({ left: 0, top: 0, height: 40, width: 250, text: 'Build Communications Array', tag: 'comms', shortcutKey: 'F1 or P', helpText: 'Regularly produces ◍ for each 🚶.', onClick: this.handleBuildButtonClicked, onEnter: this.handleBuildButtonEnter });
        public buildScienceButton = new UI.Button({ left: 0, top: 50, height: 40, width: 250, text: 'Build Research Center', tag: 'science', shortcutKey: 'F2', helpText: 'More than doubles the rate of ⓢ produced by the planet.', onClick: this.handleBuildButtonClicked, onEnter: this.handleBuildButtonEnter });
        public buildShipyardButton = new UI.Button({ left: 0, top: 100, height: 40, width: 250, text: 'Build Shipyard', tag: 'shipyard', shortcutKey: 'F3', helpText: 'Allows ships to be built.', onClick: this.handleBuildButtonClicked, onEnter: this.handleBuildButtonEnter });
        public buildScannerButton = new UI.Button({ left: 0, top: 150, height: 40, width: 250, text: 'Build Scanner', tag: 'scanner', shortcutKey: 'F4', helpText: 'Makes enemies visible when they are close to the planet.', onClick: this.handleBuildButtonClicked, onEnter: this.handleBuildButtonEnter });
        public buildMiningButton = new UI.Button({ left: 0, top: 200, height: 40, width: 250, text: 'Build Mining Base', tag: 'mine', shortcutKey: 'F5', helpText: 'Allows ◍ under the crust to be mined.', onClick: this.handleBuildButtonClicked, onEnter: this.handleBuildButtonEnter });
        public buildOrbitalButton = new UI.Button({ left: 0, top: 250, height: 40, width: 250, text: 'Build Orbital', tag: 'orbital', shortcutKey: 'F6 or O', helpText: 'Defends the planet against enemies.', onClick: this.handleBuildButtonClicked, onEnter: this.handleBuildButtonEnter });
        public buildArtilleryButton = new UI.Button({ left: 0, top: 300, height: 40, width: 250, text: 'Build Artillery', tag: 'artillery', shortcutKey: 'F7', helpText: 'Regularly launches artillery pods to depopulate nearby enemy planets.', onClick: this.handleBuildButtonClicked, onEnter: this.handleBuildButtonEnter });
        public buildPanel = new UI.Panel({ left: 140, top: 10, right: 120, bottom: 10, visible: false });

        // Set up the bottom panel

        public chatTextBox = new UI.TextBox({ top: 0, height: 25, left: 0, right: 0, onKeyDown: this.handleChatTextBoxKeyDown, placeholderText: 'Chat - Type messages here and press enter.' });
        public fpsLabel = new UI.Label({ top: 30, height: 15, right: 80, width: 80 });
        public galaxySummaryLabel = new UI.Label({ top: 30, height: 15 });
        public bottomPanel = new UI.Panel({ left: 140, bottom: 10, right: 110, height: 45 });

        // Create other panels

        public createShipPanel = new CreateShipPanel(this);
        public shipActionsPanel = new ShipActionsPanel(this);
        public researchCategoryPanel = new ResearchCategoryPanel(this);
        public researchShipPanel = new UI.Panel({ left: 350, top: 10, right: 120, bottom: 10, visible: false });
        public researchFacilityPanel = new UI.Panel({ left: 350, top: 10, right: 120, bottom: 10, visible: false });
        public researchActionPanel = new UI.Panel({ left: 350, top: 10, right: 120, bottom: 10, visible: false });
        public researchPassivePanel = new UI.Panel({ left: 350, top: 10, right: 120, bottom: 10, visible: false });

        // Combine all the panels

        public root = new UI.Panel();

        constructor() {
            this.leftPanel.controls.push(this.newFacilityButton, this.newShipButton, this.newScienceButton, this.pauseButton, this.optionsButton);
            this.buildPanel.controls.push(this.buildScannerButton, this.buildScienceButton, this.buildShipyardButton, this.buildCommsButton, this.buildMiningButton, this.buildOrbitalButton, this.buildArtilleryButton);
            this.bottomPanel.controls.push(this.chatTextBox, this.fpsLabel, this.galaxySummaryLabel);
            this.root.controls.push(this.leftPanel, this.buildPanel, this.createShipPanel.root, this.researchCategoryPanel.root, this.researchShipPanel,
                this.researchFacilityPanel, this.researchActionPanel, this.researchPassivePanel, this.shipActionsPanel.root, this.bottomPanel);
        }

        show() {
            this.updateResearchButtons();
            this.chatTextBox.visible = channel.online;
        }

        hide() {
            Notices.clearMessages();
        }

        updateResearchButtons() {

            // Add research buttons based on all available effects
            for (var category of [EffectCategory.researchFacility, EffectCategory.researchShip, EffectCategory.researchAction, EffectCategory.researchPassive]) {
                var cursorY = 0;
                var panel: UI.Panel = null;
                if (category == EffectCategory.researchFacility) panel = this.researchFacilityPanel;
                if (category == EffectCategory.researchShip) panel = this.researchShipPanel;
                if (category == EffectCategory.researchAction) panel = this.researchActionPanel;
                if (category == EffectCategory.researchPassive) panel = this.researchPassivePanel;
                panel.controls = [];
                for (var i in galaxy.effects.available) {
                    var effect = galaxy.effects.available[i];
                    if (effect.category == category) {
                        var button = new UI.Button({ left: 0, top: cursorY, width: 250, height: 30 });
                        button.text = effect.name;
                        button['helpText'] = [];
                        for (var j in effect.helpText) {
                            button['helpText'].push(effect.helpText[j]);
                        }
                        if (effect.getFurtherHelpText !== undefined) {
                            var additionalHelp = effect.getFurtherHelpText();
                            for (var j in additionalHelp) {
                                button['helpText'].push(additionalHelp[j]);
                            }
                        }
                        button.tag = effect;
                        button.onEnter = this.handleResearchButtonEnter;
                        button.onClick = this.handleResearchButtonClicked;
                        panel.controls.push(button);
                        cursorY += 40;
                    }
                }
            }
            UI.compute(UI.root, UI.Bounds.create(canvas));

            // Ensure enabled state is set properly
            this.researchCategoryPanel.indicateAvailability();
        }

        handleResearchButtonEnter(sender, e) {
            if (!sender.enabled) return;
            var parts = [{ type: 'title', text: sender.text }];
            for (var i in sender.helpText) {
                var text = sender.helpText[i];
                parts.push({ type: text == '' ? 'spacer' : 'text', text: text });
            }
            toolTipCanvas = ToolTip.render(parts);
        }

        handleResearchButtonClicked(sender, e) {
            galaxy.spendScience();
            var effect: Effect = <Effect>sender.tag;
            galaxy.effects.activate(effect);
            gameUI.updateResearchButtons();
            if (galaxy.science < galaxy.scienceThreshold) {
                gameUI.hidePanels();
            }
        }

        hidePanels() {
            this.createShipPanel.root.visible = false;
            this.researchCategoryPanel.root.visible = false;
            this.researchShipPanel.visible = false;
            this.researchFacilityPanel.visible = false;
            this.researchActionPanel.visible = false;
            this.researchPassivePanel.visible = false;
            this.buildPanel.visible = false;
        }

        handleNewFacilityButtonClicked(sender, e) {
            var visible = gameUI.buildPanel.visible;
            gameUI.hidePanels();
            gameUI.buildPanel.visible = !visible;
        }

        handleNewShipButtonClicked(sender, e) {
            var visible = gameUI.createShipPanel.root.visible;
            gameUI.hidePanels();
            gameUI.createShipPanel.root.visible = !visible;
            gameUI.createShipPanel.handleSliderValueChanged(null, null);
            gameUI.createShipPanel.updatePresetsList();
        }

        handleNewScienceButtonClicked(sender, e) {
            var visible = gameUI.researchCategoryPanel.root.visible;
            gameUI.hidePanels();
            gameUI.researchCategoryPanel.root.visible = !visible;
        }

        handlePauseButtonClicked(sender, e) {
            paused = !paused;
            if (paused) {
                gameUI.hidePanels();
                gameUI.pauseButton.text = 'Resume';
            } else {
                gameUI.pauseButton.text = 'Pause';
            }
            gameUI.newFacilityButton.visible = !paused;
            gameUI.newScienceButton.visible = !paused;
            gameUI.newShipButton.visible = !paused;
            gameUI.shipActionsPanel.root.visible = !paused;
        }

        handleOptionsButtonClicked(sender, e) {
            UI.swap(optionsUI, UI.Bounds.create(canvas));
        }

        handleBuildButtonEnter(sender, e) {
            if (!sender.enabled) return;
            var facility = BodyFacilities.getInfo(selected.body, <string>sender.tag);
            var details = [{ type: 'title', text: sender.text + (sender.shortcutKey === undefined ? '' : ' [' + sender.shortcutKey + ']') },
                           { type: 'text', text: sender.helpText },
                           { type: 'text', text: 'Cost: ◍ ' + facility.cost }]
            for (var i = 0; i < facility.stats.length; i++) {
                details.push({ type: 'text', text: facility.stats[i] });
            }
            toolTipCanvas = ToolTip.render(details);
        }

        handleBuildButtonClicked(sender, e) {
            var name = <string>sender.tag;
            var spent = false;
            var commsValue = 0;
            //#warning Create a buildFacility method in Body.ts
            var facility = BodyFacilities.getInfo(selected.body, name);
            if (galaxy.spendGold(facility.cost)) {
                if (name == 'science') selected.body.facilities.science = true;
                if (name == 'scanner') selected.body.facilities.scanner = true;
                if (name == 'shipyard') selected.body.facilities.shipyard = true;
                if (name == 'comms') selected.body.facilities.comms = true;
                if (name == 'mine') selected.body.facilities.mine = true;
                if (name == 'artillery') selected.body.facilities.artillery = new BodyFacilityArtillery();
                if (name == 'orbital') {
                    selected.body.facilities.orbitals += 1;
                    commsValue = selected.body.facilities.orbitals;
                }
                spent = true;
            }
            if (spent) {
                Sounds.play(Sounds.items.blip);

                // Notify effect subsystem
                galaxy.effects.execute((e: Effect) => { return e.facilityConstructed !== undefined },
                                       (e: Effect) => { e.facilityConstructed(selected.body, name); });

                // Notify channel
                channel.invoke.updateBodyFacility(selected.body.system.code, selected.body.code, name, commsValue);
            }
        }

        handleChatTextBoxKeyDown(sender: UI.UIControl, e: UI.InputArgs) {
            var text = gameUI.chatTextBox.text.trim();
            if (channel.online && e.key == 'Enter' && text != '') {
                channel.invoke.chat(channel.playerName + ': ' + text);
                gameUI.chatTextBox.text = '';
            }
        }

    }

}